import type { CSSProperties } from 'vue';
import { Swipe, SwipeItem } from "vant";
import type { ImageFit, Numberic, PtComponent, PtComponentConst, Source } from "../../../types";
import type { PtContainer, PtPage } from '../../../types';
import { PtData } from '@/modules/pt-page/src/PtData';
import { getRegisterComponent } from '@/modules/pt-page/src/PtRegister';
import { Icon as VanIcon } from 'vant';
import { previewImage, previewImages, previewVideo } from '@/modules/pt-page/functions';

export const name = 'carousel';

type ComponentType = typeof name;

export type Props = {
    sources: Source[];
} | {
    data: string;
}

export interface RenderOptions {
    borderRadius: Numberic;
    background: string;
    fit: ImageFit;
}

export interface ThisComponent extends PtComponent<ComponentType, Props, RenderOptions> {}

export const render = (instance: PtContainer, comp: ThisComponent | PtComponentConst): JSX.Element => {
    const { value, render } = comp;
    const carouselData: Source[] = (('data' in value) ? instance.data.get(value.data) : value.sources) || [];
    const rc = getRegisterComponent('image')!;

    const getSourceNode = (source: Source, preview = false) => {
        if (!source) {
            return (<div></div>)
        }

        const sourceNode = rc.render(instance, {
            name: 'carousel-image-box',
            type: 'image',
            value: {
                src: 'src',
            },
            options: {
                width: '100%',
                height: '100%',
            },
            render: {
                borderRadius: 6,
                background: '',
                fit: 'contain',
                preview
            }
        }, undefined, new PtData(source, ''));

        const videoTriggerStyle: CSSProperties = {
            position: 'absolute',
            top: 0,
            bottom: 0,
            left: 0,
            right: 0,
            margin: 'auto',
            height: '50px',
            width: '50px',
            color: 'white',
            fontSize: '30px',
            zIndex: 1,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
        }

        return <div style="position:relative;height:100%">
            <sourceNode />;
            {source.type == 'video' ? <VanIcon name="play-circle" style={videoTriggerStyle} /> : ''}
        </div>
    }

    const OnlySource = () => {
        const item = carouselData[0];
        const sourceNode = getSourceNode(item);

        const onClick = () => {
            if (item.type == 'image') {
                // 预览图片集
                previewImage(item.src);
            } else if (item.type == 'video') {
                // 预览视频
                previewVideo(item.raw, item.src);
            }
        }

        return <sourceNode onClick={onClick} />
    }
    
    return (carouselData.length <= 1 ? <OnlySource /> : <Swipe autoplay="10000" indicatorColor="white" lazy-render>
        {{
            default: () => (<div>
                {carouselData.map((item: Source, index: number) => {
                    const sourceNode = getSourceNode(item);
                    const onClick = () => {
                        if (item.type == 'image') {
                            // 预览图片集
                            previewImages(carouselData.filter(item => item.type == 'image').map(item => item.src), index);
                        } else if (item.type == 'video') {
                            // 预览视频
                            previewVideo(item.raw, item.src);
                        }
                    }

                    return <SwipeItem>
                        <div style="position:relative;height:100%" onClick={onClick}>
                            <sourceNode />
                        </div>
                    </SwipeItem>
                })}
            </div>),
            indicator: ({ active = 0, total }: { active: number, total: number }) => {
                const style: CSSProperties = {
                    position: 'absolute',
                    right: '5px',
                    bottom: '5px',
                    padding: '2px 5px',
                    fontSize: '12px',
                    color: 'rgba(255,255,255,0.7)',
                    background: 'rgba(0, 0, 0, 0.3)',
                }
                
                return <div style={style}>{active + 1}/{total}</div>
            }
        }}
    </Swipe>)
}

/**
 * data 映射 instance.data，是真正渲染使用数据列表
 */
export const getPreloadSource = (instance: PtPage, comp: ThisComponent | PtComponentConst, data?: PtData): Source[] => {
    const { value } = comp;
    const carouselData: Source[] = (('data' in value) ? data?.get(value.data) : value.sources) || [];

    return carouselData.filter(source => source.type == 'image');
}